﻿using System;
using System.Data.SqlServerCe;
using System.Windows;
using KBS8.Data.GdfDataFilter;
using KBS8.Presentation.MapView;
using KBS8.Shared;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace KBS8.Presentation.MainWindow
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private Map _map;
        private Point _mapCenter;

        public MainWindow()
        {
            InitializeComponent();
            /*SqlCeConnection _conn = new SqlCeConnection(@"Data Source=C:\Users\Emile\Documents\Visual Studio 2012\Projects\KBS8\KBS8\KSB8.sdf");
            SqlCeCommand cmd = new SqlCeCommand();
            cmd.Connection = _conn;
            cmd.CommandText = "SELECT * FROM AreaFeature";
            _conn.Open();
            SqlCeDataReader resultSet = cmd.ExecuteReader();

            while (resultSet.Read())
            {
                Console.WriteLine(resultSet["MaxX"]);
            }*/

            _map = new Map();

            int height = Convert.ToInt32(Math.Round(MapCanvas.ActualHeight / (_map.ZoomLevel * 50)));
            int width = Convert.ToInt32(Math.Round(MapCanvas.ActualWidth / (_map.ZoomLevel * 50)));
            Console.WriteLine(height.ToString());
            Console.WriteLine(width.ToString());
            _map.Fill(width, height);
            DrawMap();
        }

        /// <summary>
        /// Draws the map on the MapView.
        /// </summary>
        public void DrawMap()
        {
            mapCanvas.Children.Clear();
            
            double i = 0.0;

            foreach (MapTile tile in _map.Tiles)
            {
                mapCanvas.Children.Add(tile.rec);
                tile.rec.SetValue(Canvas.LeftProperty, tile.X * tile.rec.Width);
                tile.rec.SetValue(Canvas.TopProperty, tile.Y * tile.rec.Height);
                Label label = new Label();
                label.Content = tile.number.ToString();
                mapCanvas.Children.Add(label);
                label.SetValue(Canvas.LeftProperty, tile.X * tile.rec.Width);
                label.SetValue(Canvas.TopProperty, tile.Y * tile.rec.Height);
                i = i + 100;
            }
            dragCanvas.Width = _map.ZoomLevel * 50 * _map.ColumnCount;
            dragCanvas.Height = _map.ZoomLevel * 50 * _map.RowCount;
            mapCanvas.Width = _map.ZoomLevel * 50 * _map.ColumnCount;
            mapCanvas.Height = _map.ZoomLevel * 50 * _map.RowCount;

            _mapCenter.X = dragCanvas.Width / 2;
            _mapCenter.Y = dragCanvas.Height / 2;


        }

        /// <summary>
        /// This method is used for getting a MapTile when you select one on the mapCanvas.
        /// </summary>
        /// <returns>The MapTile clicked by the user.</returns>
        public MapTile GetMapTileOnClick()
        {
            Point point = Mouse.GetPosition(mapCanvas);

            double column = Math.Floor(point.X / (_map.ZoomLevel * 50));
            double row = Math.Floor(point.Y / (_map.ZoomLevel * 50));

            foreach (MapTile tile in _map.Tiles)
            {
                if (tile.X == column && tile.Y == row)
                    return tile;
            }
            return null;
        }

        /// <summary>
        /// Calculates the difference between two points. 
        /// </summary>
        /// <param name="startPos">Starting position.</param>
        /// <param name="endPos">Ending position.</param>
        /// <returns>Point with the differences between the starting and ending positions.</returns>
        private Point CalculateOffset(Point startPos, Point endPos)
        {
            Point offset = new Point();
            offset.X = endPos.X - startPos.X;
            offset.Y = endPos.Y - startPos.Y;
            return offset;
        }

        /// <summary>
        /// Loads new tiles depending on the direction in which the map is being dragged.
        /// </summary>
        /// <param name="offset">Point with the differences between the starting and ending positions.</param>
        private void LoadTilesOnDrag(Point offset)
        {
            int tileAmountX = Convert.ToInt32(Math.Round(offset.X / (_map.ZoomLevel * 50)));
            int tileAmountY = Convert.ToInt32(Math.Round(offset.Y / (_map.ZoomLevel * 50)));
            if (tileAmountX < 0)
            {
                _map.InsertTilesRight(Math.Abs(tileAmountX));
                _map.DeleteTilesLeft(Math.Abs(tileAmountX));
            }
            if (tileAmountX > 0)
            {
                _map.InsertTilesLeft(tileAmountX);
                _map.DeleteTilesRight(tileAmountX);
            }
            if (tileAmountY < 0)
            {
                _map.InsertTilesBottom(Math.Abs(tileAmountY));
                _map.DeleteTilesTop(Math.Abs(tileAmountY));
            }
            if (tileAmountY > 0)
            {
                _map.InsertTilesTop(tileAmountY);
                _map.DeleteTilesBottom(tileAmountY);
            }
            if (tileAmountX == 0 && tileAmountY == 0)
            {
                DragCanvas.SetTop(mapCanvas, 0);
                DragCanvas.SetLeft(mapCanvas, 0);
            }
            DrawMap();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {

        }

        private void mapCanvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            Point startPos = dragCanvas.origCursorLocation;
            Point endPos = Mouse.GetPosition(dragCanvas);
            Point offset = CalculateOffset(startPos, endPos);
            LoadTilesOnDrag(offset);
        }

        private void MapCanvas_MouseWheel(object sender, MouseWheelEventArgs e)
        {
            if (e.Delta > 0)
                _map.ZoomLevel++;
            else
            {
                if (_map.ZoomLevel != 1)
                    _map.ZoomLevel--;
            }
            foreach (MapTile tile in _map.Tiles)
            {
                tile.ChangeSize(_map.ZoomLevel);
            }
            DrawMap();
        }

        private void Window_SizeChanged(object sender, System.Windows.SizeChangedEventArgs e)
        {
            int height = Convert.ToInt32(Math.Round(MapCanvas.ActualHeight / (_map.ZoomLevel * 50)));
            int width = Convert.ToInt32(Math.Round(MapCanvas.ActualWidth / (_map.ZoomLevel * 50)));
            Console.WriteLine(height.ToString());
            Console.WriteLine(width.ToString());
            _map.Fill(height, width);
            DrawMap();
            Console.WriteLine(MapCanvas.ActualWidth);
        }
    }
}
